﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;

using System.Windows.Forms;

namespace 俄罗斯方块
{
    public partial class Form1 : Form
    {
        bool IsRunning=false;
        Shape shape;
        Shape newShape;
        int score = 0;
        int width = 40;
        int fontsize=16;
        Box[,] boxes = new Box[14, 20];
        int []drop_start_row=new int[20];
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            int SH = Screen.PrimaryScreen.Bounds.Height;
            int SW = Screen.PrimaryScreen.Bounds.Width;
            
            Height = (int)(SH/1080.0*890.0);
            width = (int)(SH / 1080.0 * 40.0);
            fontsize = (int)(width / 40.0 * 16);
            Height = 50+ width * 20 + 40;
            Width = 20 + width * 14 + 40 + 4 * width + 40;
            button2.Width = 4 * width;
            button2.Height = 1 * width;
            button2.Left = 20 + 14 * width + 40;
            button1.Left = button2.Left;
            button1.Width = button2.Width;
            button1.Height = button2.Height;
            button1.Top = 170 + 4 * width + 20;
            checkBox1.Left = button2.Left;
            checkBox1.Top = button2.Top + button2.Height + 10;
            create_newShape();
            shape = newShape;
            create_newShape();
            if (File.Exists("background.jpg"))
            {
                BackgroundImage = Image.FromFile("background.jpg");
                
            }
            
        }

        private void button1_Click(object sender, EventArgs e)
        {



            shape.change();
            Invalidate(true);

        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (IsRunning)
            {
                button2.Text = "继续游戏";
                IsRunning = false;
                timer1.Stop();
            }
            else
            {
                button2.Text = "暂停游戏";
                IsRunning = true;
                timer1.Start();
            }
            
            Invalidate(true);
            this.Focus();
            
        }
        bool move()
        {
            int count = 0;
            for (int i = 0; i < shape.Boxes.Length; i++)
            {
                if (shape.y + shape.row < 19)
                {
                    if (boxes[shape.x + shape.Boxes[i].x, shape.y + shape.Boxes[i].y + 1] == null)
                    {
                        count++;
                    }
                    else
                    {
                        for (int j = 0; j < shape.Boxes.Length; j++)
                        {
                            boxes[shape.x + shape.Boxes[j].x, shape.y + shape.Boxes[j].y] = shape.Boxes[j];
                            boxes[shape.x + shape.Boxes[j].x, shape.y + shape.Boxes[j].y].color = shape.color;

                        }
                        int t = 0;
                        for (int j = 0; j < shape.Boxes.Length; j++)
                        {
                            int n = 0;
                            for (int k = 0; k < 14; k++)
                            {
                                if (boxes[k, shape.y + shape.Boxes[j].y] != null)
                                {
                                    n++;
                                }

                            }
                            if (n == 14)
                            {
                                for (int k = 0; k < 14; k++)
                                {
                                    boxes[k, shape.y + shape.Boxes[j].y] = null;
                                }
                               
                                drop_start_row[t++] = shape.y + shape.Boxes[j].y;
                            }
                        }
                        score += t * 20;
                        sort(t);
                        for (int j = 0; j < t; j++)
                        {
                            drop(drop_start_row[j]);
                        }
                        shape = newShape;
                        create_newShape();
                        check();
                        break;
                    }
                }

                else
                {
                    for (int j = 0; j < shape.Boxes.Length; j++)
                    {
                        boxes[shape.x + shape.Boxes[j].x, shape.y + shape.Boxes[j].y] = shape.Boxes[j];
                        boxes[shape.x + shape.Boxes[j].x, shape.y + shape.Boxes[j].y].color = shape.color;

                    }
                    int t = 0;
                    for (int j = 0; j < shape.Boxes.Length; j++)
                    {
                        int n = 0;
                        for (int k = 0; k < 14; k++)
                        {
                            if (boxes[k, shape.y + shape.Boxes[j].y] != null)
                            {
                                n++;
                            }

                        }
                        if (n == 14)
                        {
                            for (int k = 0; k < 14; k++)
                            {
                                boxes[k, shape.y + shape.Boxes[j].y] = null;
                            }
                            drop_start_row[t++] = shape.y + shape.Boxes[j].y;
                        }
                    }
                    score += t * 20;
                    sort(t);
                    for (int j = 0; j < t; j++)
                    {
                        drop(drop_start_row[j]);

                    }
                    shape = newShape;
                    create_newShape();
                    check();
                    break;
                }
            }

            if (count == shape.Boxes.Length)
            {
                shape.move(0, 1);
                return true;
            }
            return false;

        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            move();
            if (timer1.Interval > 50)
            {
                timer1.Interval = 1000 - (score / 100) * 50;
            }
            Invalidate(true);
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {

            Graphics g = e.Graphics;
            Pen pen = new Pen(Color.White);
            pen.Width = 3;
            SolidBrush brush = new SolidBrush(Color.White);
            
            Font font = new Font("微软雅黑", fontsize);
            
            g.DrawString("得分："+score.ToString(), font, brush, 20, 5);
            g.DrawString("下一个形状:", font, brush, 20 + 14 * width + 40, 130);
            g.DrawString("-----游戏说明-----\n     上：旋转\n     左：左移\n     右：右移\n     下：下移\n空格：移动到最下面", font, brush,  14 * width + 40, 14 * width + 20); ;
            brush.Color = Color.FromArgb(150, 50 ,50,0);
            
            g.FillRectangle(brush, 20, 40, 14 * width, 20 * width);
            g.FillRectangle(brush, 20 + 14 * width + 40, 170, 4 * width, 4 * width);
            
            for (int i = 0; i < newShape.Boxes.Length;i++)
            {
                pen.Width = 3;
                Rectangle rect = new Rectangle(20 +14*width+40+  (newShape.Boxes[i].x+1) * width, 170 +  newShape.Boxes[i].y * width, width, width);

                brush.Color = newShape.color;
                g.FillRectangle(brush, rect);
                g.DrawRectangle(pen, rect);
            }
            pen.Color = Color.FromArgb(255, 100, 150, 200);
            pen.Width = 1;
            for (int i = 1; i < 20; i++)
            {
                g.DrawLine(pen, 20, 40 + i * width, 20 + 14 * width, 40+i * width);

            }
            for (int j = 1; j < 14; j++)
            {
                g.DrawLine(pen, 20+j*width, 40 , 20+j*width, 40+20 * width);
            }
            if (checkBox1.Checked)
            {
                predict(g, pen);
            }
            pen.Color = Color.White;
            pen.Width = 3;
           
            for (int i = 0; i < 20; i++)
            {
                for (int j = 0; j < 14; j++)
                {
                    Rectangle rect = new Rectangle(20 + j * width, 40 + i * width, width, width);
                    if (boxes[j, i] != null)
                    {
                        brush.Color = boxes[j, i].color;
                        g.FillRectangle(brush, rect);
                        g.DrawRectangle(pen, rect);
                    }
                    
                }

            }
            brush.Color = shape.color;
            for (int i = 0; i < shape.Boxes.Length; i++)
            {
                Rectangle rect = new Rectangle(20 + (shape.x + shape.Boxes[i].x) * width, 40 + (shape.y + shape.Boxes[i].y) * width, width, width);
               
                
                g.FillRectangle(brush, rect);
                g.DrawRectangle(pen, rect);
            }
            g.DrawRectangle(pen, new Rectangle(20, 40, 14 * width, 20 * width));
            g.DrawRectangle(pen, new Rectangle(20 + 14 * width + 40, 170, 4 * width, 4 * width));
        }
        void predict(Graphics g,Pen pen)
        {
            int y1=0, y2=0;
            for(int i = 0; i < shape.Boxes.Length; i++)
            {
                if (shape.Boxes[i].x == 0)
                {
                    if (shape.Boxes[i].y > y1)
                    {
                        y1 = shape.Boxes[i].y;
                    }

                }
                if (shape.Boxes[i].x ==  shape.col)
                {
                    if (shape.Boxes[i].y > y2)
                    {
                        y2 = shape.Boxes[i].y;
                    }
                }
            }
            pen.Width = 1;
            pen.Color = Color.White;
            pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
            pen.DashPattern = new float[] { 5, 5 };
            g.DrawLine(pen, 20 + shape.x * width, 40+(shape.y+y1)*width, 20 + shape.x * width, 40 + 20 * width);
            g.DrawLine(pen, 20 + (shape.x + shape.col+1) * width, 40 + (shape.y + y2) * width, 20 + (shape.x + shape.col+1) * width, 40 + 20 * width);
            pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
        }
        private void button3_Click(object sender, EventArgs e)
        {

        }
        void create_newShape()
        {
            Random rand = new Random();
            int x = rand.Next(100);
            int num = 7;
            if (x % num == 0)
            {
                newShape = new Shape2();
            }
            else if (x % num == 1)
            {
                newShape = new Shape1();
            }
            else if (x % num == 2)
            {
                newShape = new Shape3();
            }
            else if (x % num == 3)
            {
                newShape = new Shape4();
            }
            else if (x % num == 4)
            {
                newShape = new Shape5();
            }
            else if (x % num == 5)
            {
                newShape = new Shape6();
            }
            else if (x % num == 6)
            {
                newShape = new Shape7();
            }

            

        }
        void check()
        {
            for (int i = 0; i < shape.Boxes.Length; i++)
            {
                if (boxes[shape.x + shape.Boxes[i].x, shape.y + shape.Boxes[i].y] != null)
                {
                    EndGame();
                    MessageBox.Show("游戏结束");

                    break;
                }
            }
        }

        private void EndGame()
        {
            for(int i = 0; i < 20; i++)
            {
                for(int j = 0; j < 14; j++)
                {
                    boxes[j, i] = null;
                }
            }
            timer1.Stop();
            score = 0;
            button2.Text = "开始游戏";
            IsRunning = false;
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            
        }

        private void Form1_KeyPress(object sender, KeyPressEventArgs e)
        {

        }

        private void Form1_KeyUp(object sender, KeyEventArgs e)
        {
            
        }

        void drop(int n)
        {
           


            for (int i = 0; i < 14; i++)
            {
                for (int j = n-1; j >= 0; j--)
                {

                    

                        boxes[i, j + 1] = boxes[i, j];
                        boxes[i, j] = null;
                    
                }
            }
        }
        void sort(int n)
        {
            for(int i = 0; i < n-1; i++)
            {
                for(int j = i + 1; j < n; j++)
                {
                    if (drop_start_row[i] > drop_start_row[j])
                    {
                        int temp = drop_start_row[i];
                        drop_start_row[i] = drop_start_row[j];
                        drop_start_row[j] = temp;
                    }
                }
            }
        }

        private void button2_MouseMove(object sender, MouseEventArgs e)
        {
            
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            Invalidate(true);
        }
        
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)//取消方向键对控件的焦点的控件，用自己自定义的函数处理各个方向键的处理函数
        {
            switch (keyData)
            {
                case Keys.Up:
                    UpKey();
                    return true;//不继续处理
                case Keys.Down:
                    DownKey();
                    return true;
                case Keys.Left:
                    LeftKey();
                    return true;
                case Keys.Right:
                    RightKey();
                    return true;
                case Keys.Space:
                    SpaceKey();
                    return true;

            }
            return base.ProcessCmdKey(ref msg, keyData);
        }

        private void SpaceKey()
        {
            while (move()) ;
            Invalidate(true);
        }

        private void RightKey()
        {
            if (shape.x + shape.col < 13)
            {
                for (int i = 0; i < shape.Boxes.Length; i++)
                {
                    if (boxes[shape.x + shape.Boxes[i].x + 1, shape.y + shape.Boxes[i].y] != null)
                    {
                        return;
                    }
                }
                shape.move(1, 0);
            }
            Invalidate(true);
        }

        private void LeftKey()
        {
            if (shape.x > 0)
            {
                for (int i = 0; i < shape.Boxes.Length; i++)
                {
                    if (boxes[shape.x + shape.Boxes[i].x - 1, shape.y + shape.Boxes[i].y] != null)
                    {
                        return;
                    }
                }
                shape.move(-1, 0);
            }
            Invalidate(true);
        }

        private void DownKey()
        {
            move();
            Invalidate(true);
        }

        private void UpKey()
        {
            if (shape.x + shape.row < 14)
            {
                for (int i = 0; i < shape.Boxes.Length; i++)
                {
                    int ty = shape.Boxes[i].x;

                    int tx = shape.row - shape.Boxes[i].y;
                    if (boxes[shape.x + tx, shape.y + ty] != null)
                    {
                        return;
                    }
                }
                shape.change();
            }
            Invalidate(true);
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            openFileDialog1.ShowDialog();
            BackgroundImage.Dispose();
            BackgroundImage =Image.FromFile(openFileDialog1.FileName);
            if (File.Exists("background.jpg")){
                
               
                File.Delete("background.jpg");
            }
                BackgroundImage.Save("background.jpg");
           
        }

        private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
        {

        }
    }
    


}
